package org.stepintojava.android;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.camera.hud.controls.AnalogOnScreenControl;
import org.anddev.andengine.engine.camera.hud.controls.AnalogOnScreenControl.IAnalogOnScreenControlListener;
import org.anddev.andengine.engine.camera.hud.controls.BaseOnScreenControl;
import org.anddev.andengine.engine.handler.physics.PhysicsHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.modifier.ScaleModifier;
import org.anddev.andengine.entity.modifier.SequenceEntityModifier;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;

import android.widget.Toast;

public class AnimatedSpriteWithControl extends BaseExample {
	// ===========================================================
	// Constants
	// ===========================================================

	private static final int CAMERA_WIDTH = 480;
	private static final int CAMERA_HEIGHT = 320;

	// ===========================================================
	// Fields
	// ===========================================================

	private Camera mCamera;

	private BitmapTextureAtlas mBitmapTextureAtlas;
	// private TextureRegion mFaceTextureRegion;
	private TiledTextureRegion mFaceTextureRegion;

	private BitmapTextureAtlas mOnScreenControlTexture;
	private TextureRegion mOnScreenControlBaseTextureRegion; // 搖桿底座
	private TextureRegion mOnScreenControlKnobTextureRegion; // 搖桿把手

	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	public Engine onLoadEngine() {
		// 顯示簡短訊息， android 本身的元件
		Toast.makeText(this, "Also try tapping this AnalogOnScreenControl!",
				Toast.LENGTH_LONG).show();
		this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
				new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
				this.mCamera));
	}

	@Override
	public void onLoadResources() {
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

		this.mBitmapTextureAtlas = new BitmapTextureAtlas(128, 128,
				TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createTiledFromAsset(this.mBitmapTextureAtlas, this,
						"player.png", 0, 0, 3, 4);

		this.mOnScreenControlTexture = new BitmapTextureAtlas(256, 128,
				TextureOptions.BILINEAR_PREMULTIPLYALPHA);

		// 把兩張圖檔放在一個 texture 上
		this.mOnScreenControlBaseTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createFromAsset(this.mOnScreenControlTexture, this,
						"onscreen_control_base.png", 0, 0);
		this.mOnScreenControlKnobTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createFromAsset(this.mOnScreenControlTexture, this,
						"onscreen_control_knob.png", 128, 0);

		this.mEngine.getTextureManager().loadTextures(this.mBitmapTextureAtlas,
				this.mOnScreenControlTexture);
	}

	@Override
	public Scene onLoadScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());

		final Scene scene = new Scene();
		scene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));

		// 設定放在中間時的左上角頂點
		final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
		final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion
				.getHeight()) / 2;

		final AnimatedSprite face = new AnimatedSprite(centerX, centerY,
				this.mFaceTextureRegion);
		face.setCurrentTileIndex(0);

		final PhysicsHandler physicsHandler = new PhysicsHandler(face);
		face.registerUpdateHandler(physicsHandler);

		scene.attachChild(face);

		// 產生一個搖桿物件, 參數如下
		// x, y, camera, base textureRegion, knob textureRegion, 更新頻率, click
		// 多久觸發, listener
		final AnalogOnScreenControl analogOnScreenControl = new AnalogOnScreenControl(
				0, CAMERA_HEIGHT
						- this.mOnScreenControlBaseTextureRegion.getHeight(),
				this.mCamera, this.mOnScreenControlBaseTextureRegion,
				this.mOnScreenControlKnobTextureRegion, 0.1f, 200,
				new MyControlListener(face, physicsHandler));

		analogOnScreenControl.getControlBase().setBlendFunction(
				GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		analogOnScreenControl.getControlBase().setAlpha(0.5f);
		analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		analogOnScreenControl.getControlBase().setScale(1.25f);
		analogOnScreenControl.getControlKnob().setScale(1.25f);
		analogOnScreenControl.refreshControlKnobPosition();

		// 和加入一個 sprite 不一樣
		scene.setChildScene(analogOnScreenControl);

		return scene;
	}

	@Override
	public void onLoadComplete() {

	}

	// ===========================================================
	// Methods
	// ===========================================================

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
	private final class MyControlListener implements
			IAnalogOnScreenControlListener {
		private final AnimatedSprite face;
		private final PhysicsHandler physicsHandler;
		private short direction; // {0,1,2,3,4}={無,上,下,左,右}

		private MyControlListener(AnimatedSprite face, PhysicsHandler physicsHandler) {
			this.face = face;
			this.physicsHandler = physicsHandler;
			this.direction = 0;
		}

		// 移動搖桿可以改變速率
		@Override
		public void onControlChange(
				final BaseOnScreenControl pBaseOnScreenControl,
				final float pValueX, final float pValueY) {
			//physicsHandler.setVelocity(pValueX * 100, pValueY * 100);

			float speedX = pValueX;
			float speedY = pValueY;
			
			// 邊緣判斷
			if (pValueX > 0 && face.getX() > CAMERA_WIDTH - face.getWidth()) {
				speedX = 0.0f;
			}
			if (pValueX < 0 && face.getX() < 0) {
				speedX = 0.0f;
			}
			if (pValueY > 0 && face.getY() > CAMERA_HEIGHT - face.getHeight()) {
				speedY = 0.0f;
			}
			if (pValueY < 0 && face.getY() < 0) {
				speedY = 0.0f;
			}
			
			// 4. add following code
			float deltaX = Math.abs(pValueX);
			float deltaY = Math.abs(pValueY);
			if (deltaX > deltaY) {
				if (pValueX > 0 && direction != 4) {
					face.animate(new long[]{100, 100, 100}, 3, 5, true);
					direction = 4;
				} else if (pValueX < 0 && direction != 3) {
					face.animate(new long[]{100, 100, 100}, 9, 11, true);
					direction = 3;
				}
				physicsHandler.setVelocity(speedX * 100, 0);
			} else if (deltaX < deltaY) {
				if (pValueY > 0 && direction != 2) {
					face.animate(new long[]{100, 100, 100}, 6, 8, true);
					direction = 2;
				} else if (pValueY < 0 && direction != 1){
					face.animate(new long[]{100, 100, 100}, 0, 2, true);
					direction = 1;
				}
				physicsHandler.setVelocity(0, speedY * 100);
			} else {
				if (deltaX == 0.0f && direction != 0) {
					face.stopAnimation();
					face.setCurrentTileIndex(7);
					direction = 0;
					physicsHandler.setVelocity(0);					
				} else { // 相等但都不為 0
					physicsHandler.setVelocity(speedX * 100, 0);
					direction = (pValueX > 0) ? 4 : 3;
				}
			}
			
//			else if (deltaX == 0.0f && deltaY == 0.0f && direction != 0) {
//				face.stopAnimation();
//				face.setCurrentTileIndex(7);
//				direction = 0;
//				physicsHandler.setVelocity(0);
//			}
		}

		// 點了之後會放大
		@Override
		public void onControlClick(
				final AnalogOnScreenControl pAnalogOnScreenControl) {
			face.setCurrentTileIndex(0);
			face.registerEntityModifier(new SequenceEntityModifier(
					new ScaleModifier(0.25f, 1, 1.5f), new ScaleModifier(0.25f,
							1.5f, 1)));
			// SequenceEntityModifier: 用來存放連續的動畫演出
			// ScaleModifier: 改變大小, 參數分別為時間, 初始大小, 最終大小
		}
	}
}